﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Microsoft.HomeServer.Controls;
using System.IO;
using Microsoft.HomeServer.Common.Client;

namespace RouterControl.WhsAddIn.SettingsControls
{
	public partial class SchemaUpload : SettingsControlBase
	{
		public SchemaUpload(RouterControlSettingsTab2 tab)
			: base(tab)
		{
			if (_log.IsDebugEnabled)
				_log.Debug("Initialization start");

			try
			{
				InitializeComponent();
	
				this.lineBox.Header.Text = Properties.Resources.txtUploadRouterSchema;
                this.uploadRouterStatusText.Text = Properties.Resources.txtLoading;

				tab.OnSettingsCommitted += new RouterControlSettingsTab2.OnSettingsCommittedDelegate(tab_OnSettingsCommitted);

				// done
				if (_log.IsDebugEnabled)
					_log.Debug("Initialization done");
			}
			catch (Exception ex)
			{
				_log.Fatal("Failed to initialize", ex);

				throw;
			}
		}

		private void tab_OnSettingsCommitted(RouterControlSettingsTab2.SettingsCache cache)
		{
			StartUploadSchema();
		}

		private void StartUploadSchema()
		{
			// check for uploaded schema
			var allowed = Properties.Settings.Default.AllowSchemaUpload;

			if (!allowed)
			{
				this.uploadRouterStatusText.Text = Properties.Resources.txtUploadRouterSchemaDisabled;
				this.showSchemaLabel.Enabled = true;
                this.statusImage.Image = CommonImages.StatusCritical24;

				return;
			}

			// no router selected? or does not match selected?
			if (!_singletonService.Channel.IsDeviceSelected())
			{
				this.uploadRouterStatusText.Text = Properties.Resources.txtUploadRouterSchemaNoRouterSelected;
				this.showSchemaLabel.Enabled = false;
                this.statusImage.Image = CommonImages.StatusAtRisk24;

				return;
			}

			// start checking
			if (!this.uploadSchemaBgWorker.IsBusy)
			{
				this.showSchemaLabel.Enabled = true;
				this.allowUploadRouterSchemaCB.Enabled = false;
				this.uploadRouterStatusText.Text = Properties.Resources.txtUploadRouterSchemaCheckingId;
                this.statusImage.Image = Properties.Resources.imgProgressAnim;

				this.uploadSchemaBgWorker.RunWorkerAsync();
			}
		}

		private void schemaDbLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			var sd = _singletonService.Channel.GetSelectedDevice();

			if ((sd != null) && _tab.Settings.AllowSchemaUpload)
			{
				_tab.Services.OpenUrl(
                    Whs.Properties.Constants.SchemaDbUrl + 
                    "/?SchemaId=" + 
                    sd.Value.SchemaId +
                    "&InstanceId=" +
                    Whs.RouterControlRegistry.GetInstanceId()
                    );
			}
			else
			{
				_tab.Services.OpenUrl(
                    Whs.Properties.Constants.SchemaDbUrl +
                    "?InstanceId=" +
                    Whs.RouterControlRegistry.GetInstanceId()
                    );
			}
		}

		private void showSchemaLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			if (_log.IsDebugEnabled)
				_log.Debug("Showing schema start");

			// prepare
			var sd = this._singletonService.Channel.GetSelectedDevice();

			if (sd != null)
			{
				try
				{
					// write to local file
					var schemaFile = new FileInfo(string.Format(
						@"d:\shares\{0}",
						Properties.Settings.Default.RouterSchemaTempLocation
						));

					using (var fs = schemaFile.Create())
					{
						using (var stream = _singletonService.Channel.GetSelectedDeviceSchema())
                        {
                            var buf = new byte[4096];

                            for (int r = stream.Read(buf, 0, buf.Length); r > 0; r = stream.Read(buf, 0, buf.Length))
                            {
                                fs.Write(buf, 0, r);
                            }
                        }
					}

					// open url
					var url = string.Format(
						@"file://\\{0}\{1}",
						Environment.MachineName,
						Properties.Settings.Default.RouterSchemaTempLocation
						);

					_tab.Services.OpenUrl(url);

					// prepare for deletion
					QMessageBox.Show(
						Properties.Resources.txtShowSchemaDeleteText,
						Properties.Resources.txtShowSchemaDeleteTitle,
						MessageBoxButtons.OK,
						MessageBoxIcon.Information
						);

					// finalize
					schemaFile.Delete();

					if (_log.IsDebugEnabled)
						_log.Debug("Showing schema done");
				}
				catch (Exception x)
				{
                    var dev = _singletonService.Channel.GetSelectedDevice();

					_log.Error("Failed to show schema for ID " + (dev.HasValue ? dev.Value.SchemaId : "<no device selected>"), x);

					QMessageBox.Show(
						x.Message,
						Properties.Resources.txtShowSchemaFailed,
						MessageBoxButtons.OK,
						MessageBoxIcon.Error
						);
				}
			}
		}

		private void allowUploadRouterSchemaCB_CheckedChanged(object sender, EventArgs e)
		{
			// any change?
			if (this.allowUploadRouterSchemaCB.Checked == _tab.Settings.AllowSchemaUpload)
				return;

			// ask on activation
			if (this.allowUploadRouterSchemaCB.Checked &&
				QMessageBox.Show(
					Properties.Resources.txtUploadRouterSchemaActivateMBText,
					Properties.Resources.txtUploadRouterSchemaActivateMBTitle,
					MessageBoxButtons.YesNo,
					MessageBoxIcon.Question
				) != DialogResult.Yes)
			{
				this.allowUploadRouterSchemaCB.Checked = false;

				return;
			}

			// save settings
			_tab.Settings.AllowSchemaUpload = this.allowUploadRouterSchemaCB.Checked;

			_tab.Services.EnableSettingsApply();
		}

		private void SchemaUpload_Load(object sender, EventArgs e)
		{
			if (_log.IsDebugEnabled)
				_log.Debug("Loading start");

			try
			{
				// load settings
				this.allowUploadRouterSchemaCB.Checked = _tab.Settings.AllowSchemaUpload;
	
				// start upload
				StartUploadSchema();

				// done
				if (_log.IsDebugEnabled)
					_log.Debug("Loading done");
			}
			catch (Exception ex)
			{
				_log.Fatal("Loading failed", ex);

				throw;
			}
		}

		private void uploadSchemaBgWorker_DoWork(object sender, DoWorkEventArgs e)
		{
			try
			{
				this.uploadSchemaBgWorker.ReportProgress(0, Properties.Resources.txtUploadRouterSchemaCheckingId);

				// check for existing id
				if (!_singletonService.Channel.RequiresSelectedDeviceSchemaUpload())
				{
					this.uploadSchemaBgWorker.ReportProgress(100, Properties.Resources.txtUploadRouterSchemaAlreadyUploaded);

					return;
				}

				// upload schema
				this.uploadSchemaBgWorker.ReportProgress(50, Properties.Resources.txtUploadRouterSchemaUploading);

				_singletonService.Channel.UploadSelectedDeviceSchema();

				// done
				this.uploadSchemaBgWorker.ReportProgress(100, Properties.Resources.txtUploadRouterSchemaUploaded);

			}
			catch (Exception x)
			{
                var dev = _singletonService.Channel.GetSelectedDevice();

				_log.Error("Schema upload failed for ID " + (dev.HasValue ? dev.Value.SchemaId : "<no device selected>"), x);

				this.uploadSchemaBgWorker.ReportProgress(
					-1,
					string.Format(
						Properties.Resources.txtUploadRouterSchemaFailure,
						x.Message
				));
			}
		}

		private void uploadSchemaBgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
		{
			var str = e.UserState as string;

			if (!string.IsNullOrEmpty(str))
			{
				this.uploadRouterStatusText.Text = str;

				// error msg?
                if (e.ProgressPercentage < 0)
                {
                    this.statusImage.Image = CommonImages.StatusCritical24;

                    QMessageBox.Show(
                        str,
                        Properties.Resources.txtUploadRouterSchemaFailureMBTitle,
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error
                        );
                }
                else if (e.ProgressPercentage >= 100)
                {
                    this.statusImage.Image = CommonImages.StatusHealthy24;
                }
                else
                {
                    this.statusImage.Image = Properties.Resources.imgProgressAnim;
                }
			}
		}

		private void uploadSchemaBgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			this.allowUploadRouterSchemaCB.Enabled = true;
		}
	}
}
